﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading.Tasks;
using Acme.BookStore2.Permissions;
using Microsoft.AspNetCore.Authorization;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Services;
using Volo.Abp.Identity;
using Volo.Abp.ObjectExtending;

namespace Acme.BookStore2
{
    [Authorize(BookStore2Permissions.VehicleInspectionRecord.Default)]
    public class VehicleInspectionRecordAppService : ApplicationService, IVehicleInspectionRecordAppService
    {
        private readonly IVehicleInspectionRecordRepository _vehicleInspectionRecordRepository;
        private readonly VehicleInspectionRecordManager _vehicleInspectionRecordManager;
        private readonly IIdentityUserRepository _userRepository;
        public VehicleInspectionRecordAppService(
            IVehicleInspectionRecordRepository vehicleInspectionRecordRepository, 
            VehicleInspectionRecordManager vehicleInspectionRecordManager, IIdentityUserRepository userRepository)
        {
            _vehicleInspectionRecordRepository = vehicleInspectionRecordRepository;
            _vehicleInspectionRecordManager = vehicleInspectionRecordManager;
            _userRepository = userRepository;
        }

        public async Task<VehicleInspectionRecordDto> GetAsync(Guid id)
        {
            var inspectionRecord = await _vehicleInspectionRecordRepository.GetAsync(id, false);
            var inspectionRecordDto = ObjectMapper.Map<VehicleInspectionRecord, VehicleInspectionRecordDto>(inspectionRecord);
            if (inspectionRecord.CreatorId.HasValue)
            {
                var creator = await _userRepository.GetAsync(inspectionRecord.CreatorId.Value);
                inspectionRecordDto.CreatorName = creator.Name + " " + creator.Surname;
            }
            return inspectionRecordDto;
        }

        public async Task<PagedResultDto<VehicleInspectionRecordDto>> GetPagedListAsync(GetVehicleInspectionRecordsInput input)
        {
            var count = await _vehicleInspectionRecordRepository.GetCountAsync(input.VehicleId);
            var list = await _vehicleInspectionRecordRepository.GetPagedListAsync(input.SkipCount, input.MaxResultCount,
                input.Sorting, input.VehicleId);
            var pageDto = new PagedResultDto<VehicleInspectionRecordDto>(
                count, 
                ObjectMapper.Map<List<VehicleInspectionRecord>, List<VehicleInspectionRecordDto>>(list));
            foreach (var dto in pageDto.Items)
            {
                if (dto.CreatorId.HasValue)
                {
                    var creator = await _userRepository.GetAsync(dto.CreatorId.Value);
                    dto.CreatorName = creator.Name + " " + creator.Surname;
                }
            }
            return pageDto;
        }

        [Authorize(BookStore2Permissions.VehicleInspectionRecord.Create)]
        public async Task<VehicleInspectionRecordDto> CreateAsync(VehicleInspectionRecordCreateDto input)
        {
            var vehicleInspectionRecord = new VehicleInspectionRecord(
                GuidGenerator.Create(),
                input.VehicleId,
                CurrentTenant.Id);

            UpdateVehicleInspectionRecord(vehicleInspectionRecord, input);
            input.MapExtraPropertiesTo(vehicleInspectionRecord);

            await _vehicleInspectionRecordManager.CreateAsync(vehicleInspectionRecord);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<VehicleInspectionRecord, VehicleInspectionRecordDto>(vehicleInspectionRecord);
        }

        [Authorize(BookStore2Permissions.VehicleInspectionRecord.Update)]
        public async Task<VehicleInspectionRecordDto> UpdateAsync(Guid id, VehicleInspectionRecordUpdateDto input)
        {
            var vehicleInspectionRecord = await _vehicleInspectionRecordRepository.GetAsync(id);
            vehicleInspectionRecord.ConcurrencyStamp = input.ConcurrencyStamp;

            UpdateVehicleInspectionRecord(vehicleInspectionRecord, input);
            input.MapExtraPropertiesTo(vehicleInspectionRecord);

            await _vehicleInspectionRecordManager.UpdateAsync(vehicleInspectionRecord);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<VehicleInspectionRecord, VehicleInspectionRecordDto>(vehicleInspectionRecord);
        }

        [Authorize(BookStore2Permissions.VehicleInspectionRecord.Delete)]
        public async Task DeleteAsync(Guid id)
        {
            var vehicleInspectionRecord = await _vehicleInspectionRecordRepository.FindAsync(id);
            if (vehicleInspectionRecord == null)
            {
                return;
            }

            await _vehicleInspectionRecordManager.DeleteAsync(vehicleInspectionRecord);
        }

        [Authorize(BookStore2Permissions.VehicleInspectionRecord.Export)]
        public async Task ExportAsync(GetVehicleInspectionRecordsInput input)
        {
        }

        private void UpdateVehicleInspectionRecord(VehicleInspectionRecord vehicleInspectionRecord, VehicleInspectionRecordCreateOrUpdateDtoBase input)
        {
            vehicleInspectionRecord.Cleanliness = input.Cleanliness;
            vehicleInspectionRecord.EngineLight = input.EngineLight;
            vehicleInspectionRecord.RemainFuel = input.RemainFuel;
            vehicleInspectionRecord.TirePressure = input.TirePressure;
            vehicleInspectionRecord.WindshieldFluid = input.WindshieldFluid;
            vehicleInspectionRecord.Remark = input.Remark;
            vehicleInspectionRecord.CurrentKilometers = input.CurrentKilometers;
            
            ObjectMapper.Map(input.AttachFiles, vehicleInspectionRecord.AttachFiles);
        }
    }
}